package hao.itheima.controller;

import hao.itheima.entity.Dept;
import hao.itheima.entity.Result;
import hao.itheima.service.DeptService;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;

//@Component // 注意: @Controller不能用@Component代替
@RestController // 表示这个是一个请求处理类     @RestController = @Controller + @ResponseBody
//@Controller
//@ResponseBody   作用: 返回数据是对象或集合的时候, 自动转换成json格式返回

@Slf4j
@RequestMapping("/depts")
public class DeptController {

    //可以写在下面
    //@ResponseBody
    /*@RequestMapping("/depts")// 表示请求映射, 也就是请求路径, 需要根据接口文档书写
    public List<Dept> getAll(){
        System.out.println("查询所有部门信息");
        //1、加载并读取det.txt文件
        //现在一般不会使用底层的流了(过于底层效率太低了), 一般都是使用框架例如 commons-io
        //获取input的思路 1.可以直接new 一个字节输入流
        //FileInputStream input = new FileInputStream("dept.txt");
        //              2.通过类加载器获取文件输入流
        //              原因:在resources目录下的资源文件,都会被遍历到target/classes目录下
        //                                  这个称为类路径
        //通过类加载器可以获取类路径下的所有资源
        InputStream input = this.getClass().getClassLoader().getResourceAsStream("dept.txt");
        //一行一行的读,读完之后会返回一个集合
        List<String> strings = IOUtils.readLines(input, "UTF-8");
        //2、解析文本中的数据, 并将其封装成集合
        //使用stream()做
        List<Dept> depts = strings.stream().map((str) -> {
            //1.安装要去截取字符串
            String[] split = str.split(",");
            //2.获取数组中的每一个数据
            Integer id = Integer.parseInt(split[0]);
            String name = split[1];
            LocalDateTime update = LocalDateTime.parse(split[2], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            //3.创建对象并返回
            return new Dept(id, name, update);
        }).collect(Collectors.toList());// 可以简写成.toList();

        //3、响应数据(json格式)
        //直接返回即可,会直接是json格式的
        //为什么返回出去就是json格式呢?
        //
        return depts;
    }*/

    //统一响应结果
    //统一请求方式
    //                                     这是一个数组,可以放多个
    //                                              ↓
    //@RequestMapping(value = "/depts", method = RequestMethod.GET)// 表示请求映射, 也就是请求路径, 需要根据接口文档书写
    //简略写法
    /*   @GetMapping("/depts")
    public Result getAll(){
        System.out.println("查询所有部门信息");
        //1、加载并读取det.txt文件
        //现在一般不会使用底层的流了(过于底层效率太低了), 一般都是使用框架例如 commons-io
        //获取input的思路 1.可以直接new 一个字节输入流
        //FileInputStream input = new FileInputStream("dept.txt");
        //              2.通过类加载器获取文件输入流
        //              原因:在resources目录下的资源文件,都会被遍历到target/classes目录下
        //                                  这个称为类路径
        //通过类加载器可以获取类路径下的所有资源
        InputStream input = this.getClass().getClassLoader().getResourceAsStream("dept.txt");
        //一行一行的读,读完之后会返回一个集合
        List<String> strings = IOUtils.readLines(input, "UTF-8");
        //2、解析文本中的数据, 并将其封装成集合
        //使用stream()做
        List<Dept> depts = strings.stream().map((str) -> {
            //1.安装要去截取字符串
            String[] split = str.split(",");
            //2.获取数组中的每一个数据
            Integer id = Integer.parseInt(split[0]);
            String name = split[1];
            LocalDateTime update = LocalDateTime.parse(split[2], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            //3.创建对象并返回
            return new Dept(id, name, update);
        }).collect(Collectors.toList());// 可以简写成.toList();

        //3、响应数据(json格式)
        //直接返回即可,会直接是json格式的
        //为什么返回出去就是json格式呢?
        //
        //为什么要调用sucess, 执行到这里上面的代码也是正确的了
        return Result.success(depts);
    }*/

    //1、创建service的对象
    //这里就可以改造成面向接口编程了
//   private DeptService deptService = new DeptServiceImpl();
//    @Autowired // 从spring容器(IOC容器)中, 自动寻找Bean对象, 为该变量赋值 --- 依赖注入DI的实现[--根据类型注入,实现同一个接口,注入的类型一样--]
//    @Qualifier("service") // 根据Bean的名字注入 如果没有给并起名字,名字就是类名,但是首字母要小写
    @Resource(name = "service") // 也是根据bean的名字注入对象 , 等价与@Autowired + @Qualifier
    private DeptService deptService;

    @GetMapping // @RequestMapping("/depts")将公共路径, 抽取到类上了, 这里就得删除
    public Result getAll() {
//        System.out.println("被访问了一次");
        log.info("被访问了一次");
        //1.调用service, 获取数据
        List<Dept> depts = deptService.list();
        //2.返回数据
        return Result.success(depts);
    }


   /* //接受前端参数方式一: 原始的获取请求参数, 通过HttpServletRequest对象获取
    //定义一个功能接口, 其实就是一个方法, 根据接口文档进行定义
//    @RequestMapping(value = "/depts", method = RequestMethod.DELETE)
    @DeleteMapping("/depts") //真正要使用的注解, 简写, 里面对RequesMapping进行了封装
    public Result delete(HttpServletRequest request) {
        String id = request.getParameter("id");
        int idInt = Integer.parseInt(id);
        System.out.println("id" + idInt);
        return Result.success();
    }*/


    /*//方式二: 通过spring提供的@RequestParam注解获取请求参数
    //@RequestParam加上之后, request的值是true代表前端必须传参数(且参数名必须跟注解括号里面写的一样), 否则报错 400 Bad Request, 如果不需要限制, 可以将其设置参false,格式如下
    //public Result delete(@RequestParam(value = "id" , required = false) Integer deptId)
    //应用场景: 是false的时候, 很多框就不用填,
    //        是true的时候, 某些框必须填, 否则报错 400 Bad Request
    @DeleteMapping("/depts") //真正要使用的注解, 简写, 里面对RequestMapping进行了封装
    //形参类型: 看接口文档, 数字类型就写 Integer Long, 一般都是能接受到的
    //                           这样子就会映射上, 映射上了, 才会将数据封装到deptId中
    public Result delete(@RequestParam(value = "id" , required = false) Integer deptId) {
        System.out.println("deptId = " + deptId);
        return Result.success();
    }*/
    //方式三: 如果请求参数名与形参变量名相同, 直接定义方法形参即可接收(省略@RequestParam)
    //@RequestParam加上之后, request的值是true代表前端必须传参数(且参数名必须跟注解括号里面写的一样), 否则报错 400 Bad Request, 如果不需要限制, 可以将其设置参false,格式如下
    //public Result delete(@RequestParam(value = "id" , required = false) Integer deptId)
    //应用场景: 是false的时候, 很多框就不用填,
    //        是true的时候, 某些框必须填, 否则报错 400 Bad Request
    @DeleteMapping //真正要使用的注解, 简写, 里面对RequestMapping进行了封装
    //形参类型: 看接口文档, 数字类型就写 Integer Long, 一般都是能接受到的(就严格按照接口文档书写就可以了)
    //                           这样子就会映射上, 映射上了, 才会将数据封装到deptId中
    public Result delete(Integer id) {
//        System.out.println("deptId = " + id);
        log.info("id = {}" , id);// 使用占位符的形式, 的用逗号, 没有进行字符串的拼接, 性能更好一点
        //调用service层的删除方法
        //需不需要返回参数, 直接看接口文档, 如果data,没有数据就是不需要返回参数
        deptService.delete(id);
        return Result.success();
    }


    @PostMapping
    public Result save(@RequestBody Dept dept) {
        //开发的时候,也可以这样子, 写一步测一步, 看效果能不能执行到这里
//        System.out.println("dept = " + dept);
        deptService.save(dept);
        return Result.success();
    }

    /**
     * 数据回显
     * @param id
     * @return
     */

    //@PathVariable注解: 获取路径中的参数(用于接收路径参数值)
    @GetMapping("/{id}")//回显  @PathVariable注解: 获取路径中的参数
    public Result getById(@PathVariable Integer id) {
        //System.out.println("id = " + id);
        log.info("id = {}" , id);
        //1.调用service层方法
        Dept dept = deptService.getById(id);
        return Result.success(dept);
    }


    @PutMapping
    public Result update(@RequestBody Dept dept){
//        System.out.println("dept = " + dept);
        log.info("dept = {}" , dept);
        deptService.update(dept);
        return Result.success();
    }

}
